using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;

namespace demo
{
    /// <summary>
    /// 用户登录信息管理类（本地文件 UserLoginConfig.xml）
    /// </summary>
    public static class UserLoginManager
    {
        private static readonly string ConfigFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UserLoginConfig.xml");
        private const int PasswordValidDays = 3; // 密码有效期3天

        /// <summary>
        /// 用户登录信息
        /// </summary>
        public class UserLoginInfo
        {
            public string UserId { get; set; }
            public string EncryptedPassword { get; set; }
            public DateTime LastLoginTime { get; set; }
            public string ComputerName { get; set; }
            public string DeptName { get; set; }
            public string OrgCode { get; set; }
        }

        /// <summary>
        /// 用户科室信息
        /// </summary>
        public class UserDeptInfo
        {
            public string DeptName { get; set; }
            public string OrgCode { get; set; }
        }

        // 当前登录用户的科室信息缓存，方便程序随时调用
        public static string CurrentDeptName { get; private set; }
        public static string CurrentOrgCode { get; private set; }

        /// <summary>
        /// 保存用户登录信息（含加密密码与登录时间）
        /// </summary>
        public static void SaveUserLoginInfo(string userId, string password)
        {
            try
            {
                var allUsers = LoadAllUserLoginInfo();
                var existing = allUsers.FirstOrDefault(u => u.UserId == userId);

                if (existing != null)
                {
                    // 更新密码、时间和机器名，保留已选择的科室信息
                    existing.EncryptedPassword = PasswordEncryption.Encrypt(password);
                    existing.LastLoginTime = DateTime.Now;
                    existing.ComputerName = Environment.MachineName;
                }
                else
                {
                    // 新用户记录，科室信息为空，待后续选择
                    var userInfo = new UserLoginInfo
                    {
                        UserId = userId,
                        EncryptedPassword = PasswordEncryption.Encrypt(password),
                        LastLoginTime = DateTime.Now,
                        ComputerName = Environment.MachineName,
                        DeptName = string.Empty,
                        OrgCode = string.Empty
                    };
                    allUsers.Add(userInfo);
                }

                SaveAllUserLoginInfo(allUsers);
            }
            catch (Exception ex)
            {
                throw new Exception($"保存用户登录信息失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取用户密码（若有效），否则返回 null
        /// </summary>
        public static string GetUserPassword(string userId)
        {
            try
            {
                var allUsers = LoadAllUserLoginInfo();
                var userInfo = allUsers.FirstOrDefault(u => u.UserId == userId);
                if (userInfo == null)
                    return null;
                if (userInfo.ComputerName != Environment.MachineName)
                    return null;
                if (DateTime.Now.Subtract(userInfo.LastLoginTime).TotalDays > PasswordValidDays)
                    return null;
                return PasswordEncryption.Decrypt(userInfo.EncryptedPassword);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取用户密码时发生错误: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 获取当前计算机上、仍在有效期内的用户名列表
        /// </summary>
        public static List<string> GetValidUserNames()
        {
            try
            {
                var allUsers = LoadAllUserLoginInfo();
                var validUsers = allUsers
                    .Where(u => u.ComputerName == Environment.MachineName &&
                                DateTime.Now.Subtract(u.LastLoginTime).TotalDays <= PasswordValidDays)
                    .Select(u => u.UserId)
                    .ToList();
                return validUsers;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取有效用户名列表时发生错误: {ex.Message}");
                return new List<string>();
            }
        }

        /// <summary>
        /// 获取最后登录的用户名（当前计算机）
        /// </summary>
        public static string GetLastLoginUser()
        {
            try
            {
                var allUsers = LoadAllUserLoginInfo();
                var lastUser = allUsers
                    .Where(u => u.ComputerName == Environment.MachineName)
                    .OrderByDescending(u => u.LastLoginTime)
                    .FirstOrDefault();
                return lastUser?.UserId;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取最后登录用户时发生错误: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 清理过期的用户信息
        /// </summary>
        public static void CleanExpiredUserInfo()
        {
            try
            {
                var allUsers = LoadAllUserLoginInfo();
                var validUsers = allUsers
                    .Where(u => DateTime.Now.Subtract(u.LastLoginTime).TotalDays <= PasswordValidDays)
                    .ToList();
                SaveAllUserLoginInfo(validUsers);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清理过期用户信息时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 检查指定用户是否可以自动填充密码（最后登录且密码有效）
        /// </summary>
        public static bool CanAutoFillPassword(string userId)
        {
            try
            {
                var lastLoginUser = GetLastLoginUser();
                var userPassword = GetUserPassword(userId);
                return lastLoginUser == userId && !string.IsNullOrEmpty(userPassword);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"检查自动填充权限时发生错误: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 加载所有用户登录信息
        /// </summary>
        private static List<UserLoginInfo> LoadAllUserLoginInfo()
        {
            var users = new List<UserLoginInfo>();
            try
            {
                if (!File.Exists(ConfigFilePath))
                    return users;

                var doc = new XmlDocument();
                doc.Load(ConfigFilePath);

                var userNodes = doc.SelectNodes("//User");
                if (userNodes != null)
                {
                    foreach (XmlNode node in userNodes)
                    {
                        var userInfo = new UserLoginInfo
                        {
                            UserId = node.SelectSingleNode("UserId")?.InnerText ?? string.Empty,
                            EncryptedPassword = node.SelectSingleNode("EncryptedPassword")?.InnerText ?? string.Empty,
                            ComputerName = node.SelectSingleNode("ComputerName")?.InnerText ?? string.Empty
                        };

                        userInfo.DeptName = node.SelectSingleNode("DeptName")?.InnerText ?? string.Empty;
                        userInfo.OrgCode = node.SelectSingleNode("OrgCode")?.InnerText ?? string.Empty;

                        DateTime lastLogin;
                        if (DateTime.TryParse(node.SelectSingleNode("LastLoginTime")?.InnerText, out lastLogin))
                        {
                            userInfo.LastLoginTime = lastLogin;
                        }

                        if (!string.IsNullOrEmpty(userInfo.UserId))
                        {
                            users.Add(userInfo);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"加载用户登录信息时发生错误: {ex.Message}");
            }

            return users;
        }

        /// <summary>
        /// 保存所有用户登录信息
        /// </summary>
        private static void SaveAllUserLoginInfo(List<UserLoginInfo> users)
        {
            try
            {
                var doc = new XmlDocument();
                var declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                doc.AppendChild(declaration);

                var root = doc.CreateElement("UserLoginConfig");
                doc.AppendChild(root);

                foreach (var user in users)
                {
                    var userNode = doc.CreateElement("User");

                    var userIdNode = doc.CreateElement("UserId");
                    userIdNode.InnerText = user.UserId;
                    userNode.AppendChild(userIdNode);

                    var passwordNode = doc.CreateElement("EncryptedPassword");
                    passwordNode.InnerText = user.EncryptedPassword;
                    userNode.AppendChild(passwordNode);

                    var timeNode = doc.CreateElement("LastLoginTime");
                    timeNode.InnerText = user.LastLoginTime.ToString("yyyy-MM-dd HH:mm:ss");
                    userNode.AppendChild(timeNode);

                    var computerNode = doc.CreateElement("ComputerName");
                    computerNode.InnerText = user.ComputerName;
                    userNode.AppendChild(computerNode);

                    var deptNode = doc.CreateElement("DeptName");
                    deptNode.InnerText = user.DeptName ?? string.Empty;
                    userNode.AppendChild(deptNode);

                    var orgCodeNode = doc.CreateElement("OrgCode");
                    orgCodeNode.InnerText = user.OrgCode ?? string.Empty;
                    userNode.AppendChild(orgCodeNode);

                    root.AppendChild(userNode);
                }

                doc.Save(ConfigFilePath);
            }
            catch (Exception ex)
            {
                throw new Exception($"保存用户登录信息时发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取指定用户的科室信息（若存在且在有效期内），并更新当前缓存
        /// </summary>
        public static UserDeptInfo GetUserDeptInfo(string userId)
        {
            try
            {
                var allUsers = LoadAllUserLoginInfo();
                var userInfo = allUsers.FirstOrDefault(u => u.UserId == userId);

                // 当密码缓存失效或计算机不匹配时，科室信息也视为失效
                if (userInfo == null ||
                    userInfo.ComputerName != Environment.MachineName ||
                    DateTime.Now.Subtract(userInfo.LastLoginTime).TotalDays > PasswordValidDays)
                {
                    CurrentDeptName = string.Empty;
                    CurrentOrgCode = string.Empty;
                    return new UserDeptInfo { DeptName = string.Empty, OrgCode = string.Empty };
                }

                var deptName = userInfo.DeptName ?? string.Empty;
                var orgCode = userInfo.OrgCode ?? string.Empty;
                CurrentDeptName = deptName;
                CurrentOrgCode = orgCode;
                return new UserDeptInfo { DeptName = deptName, OrgCode = orgCode };
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取用户科室信息时发生错误: {ex.Message}");
                return new UserDeptInfo { DeptName = string.Empty, OrgCode = string.Empty };
            }
        }

        /// <summary>
        /// 更新并保存指定用户的科室信息，同时更新当前缓存
        /// </summary>
        public static void SetUserDeptInfo(string userId, string deptName, string orgCode)
        {
            try
            {
                var allUsers = LoadAllUserLoginInfo();
                var userInfo = allUsers.FirstOrDefault(u => u.UserId == userId);
                if (userInfo == null)
                {
                    userInfo = new UserLoginInfo
                    {
                        UserId = userId,
                        EncryptedPassword = string.Empty,
                        LastLoginTime = DateTime.Now,
                        ComputerName = Environment.MachineName
                    };
                    allUsers.Add(userInfo);
                }

                userInfo.DeptName = deptName ?? string.Empty;
                userInfo.OrgCode = orgCode ?? string.Empty;

                SaveAllUserLoginInfo(allUsers);

                CurrentDeptName = userInfo.DeptName;
                CurrentOrgCode = userInfo.OrgCode;
            }
            catch (Exception ex)
            {
                throw new Exception($"保存用户科室信息失败: {ex.Message}", ex);
            }
        }
    }
}